﻿using log4net;
using Mangox.Common;
using Mangox.DAL;
using Mangox.Model.Common;
using Mangox.Model.Stock;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;

namespace Mangox.BLL.Stock
{
    public class StockBLL
    {
        static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        public static string zhangDieTing = ConfigurationManager.AppSettings["ZhangDieTing"];
        public static string qtMarketUrl = ConfigurationManager.AppSettings["qtMarket"];
        public static string holidaysApi = ConfigurationManager.AppSettings["HolidaysApi"];

        public static string zhiShu = ConfigurationManager.AppSettings["ZhiShu"];
        public static string etfCode = ConfigurationManager.AppSettings["ETFCode"];
        public static string weightCode = ConfigurationManager.AppSettings["WeightCode"]; 
        public static string gangMeiCode = ConfigurationManager.AppSettings["GangMeiCode"];

        public static string tmtUpUrl = ConfigurationManager.AppSettings["tmtUpUrl"];
        public static string tmtDownUrl = ConfigurationManager.AppSettings["tmtDownUrl"];
        public static string conceptUpUrl = ConfigurationManager.AppSettings["conceptUpUrl"];
        public static string conceptDownUrl = ConfigurationManager.AppSettings["conceptDownUrl"];
        public static string IndUpUrl = ConfigurationManager.AppSettings["IndUpUrl"];
        public static string IndDownUrl = ConfigurationManager.AppSettings["IndDownUrl"];

        public static string sinaStockPortUrl = ConfigurationManager.AppSettings["sinaStockDataPort"];


        public static object obj = new object();
        public static MarketBriefTencent stockData = new MarketBriefTencent();  //使用全局缓存起来
        public static MarketBriefTencent stockBlockData = new MarketBriefTencent();  //使用全局缓存起来
        public static HoliDayModel holi = new HoliDayModel();//缓存一天 节日api
        public static Random random = new Random();


        //public static List<MarketBriefStock> tmtUpList = null;
        MarketBriefStock mksModel = null;


        /// <summary>
        /// 默认涨跌幅
        /// </summary>
        //public static double zhangFuDefault = Convert.ToDouble(ConfigurationManager.AppSettings["ZhangFu"]);
        //public static double dieFuDefault = Convert.ToDouble(ConfigurationManager.AppSettings["DieFu"]);
        /// <summary>
        /// 默认当日提醒间隔（分）
        /// </summary>
        public static double tiXingDefault = Convert.ToDouble(ConfigurationManager.AppSettings["RemindInterval"]);

        public static double zhangFu = 0;
        public static double dieFu = 0;
        public static double tiXing = 0;


        /// <summary>
        /// 涨跌停家数行情 - 金融界
        /// </summary>
        public MarketModel GetZdt()
        {
            JsonRequest request = new JsonRequest();
            MarketModel model = null;
            string url = null;
            string result = null;
            try
            {
                url = zhangDieTing + random.Next(10, 10000);
                result = request.Get(url).Replace("var market=", "").Replace(";", "");
                model = JsonCommon.JsonToMode<MarketModel>(result);
            }
            catch (Exception ex)
            {
                var logInfo = string.Format("StockBLL/GetZdt url-{0}，result-{1}，Fail-{2}", url, result, ex.ToString());
                log.Info(logInfo);
                //StockCommBLL.SendEmail("系统异常", "StockBLL/GetZdt", logInfo);
            }
            return model;
        }

        
        /// <summary>
        /// 获取腾讯网 上证指数，创业板指，沪A，深A 涨跌家数
        /// </summary>
        /// <returns></returns>
        public string GetQtMarket()
        {
            string url = null;
            string result = null;
            try
            {
                JsonRequest request = new JsonRequest();
                url = qtMarketUrl + "s_sh000001,s_sz399006,bkqtRank_A_sh,bkqtRank_A_sz,s_sh510050,s_sz159949&r=" + random.Next(10, 10000) + "";
                result = request.Get(url, null, Encoding.GetEncoding("gb2312"));
            }
            catch (Exception ex)
            {
                var logInfo = string.Format("StockBLL/GetQtMarket url-{0}，result-{1}，Fail-{2}", url, result, ex.ToString());
                log.Info(logInfo);
                //StockCommBLL.SendEmail("系统异常", "StockBLL/GetQtMarket", logInfo);
            }
            return result;
        }

        #region Out WeiChar UWP 对外接口

        

        /// <summary>
        /// 获取新浪行情，个股代码
        /// 也可拼接多个代码
        /// API调用重载
        /// </summary>
        /// <returns></returns>
        public List<StockModel> GetSinaMarket(StockPoolReq param)
        {
            JsonRequest request = new JsonRequest();
            string url = null;
            string result = null;
            List<StockModel> stockList = null;
            try
            {
                if (param.BazaarType == BazaarType.SH)
                {
                    param.StockCode = "sh" + param.StockCode;
                }

                url = sinaStockPortUrl + param.StockCode;
                //url = "http://hq.sinajs.cn/list=sh600000";
                result = request.Get(url, null, Encoding.GetEncoding("gb2312"));

                //var pageList = JsonCommon.JsonToMode<StockModel>(result);
                stockList = GetStockInfo2(result);
            }
            catch (Exception ex)
            {
                var logInfo = string.Format("StockBLL/GetSinaMarket url-{0}，result-{1}，Fail-{2}", url, result, ex.ToString());
                log.Info(logInfo);
            }
            return stockList;
        }

        /// <summary>
        /// 获取市场类型函数
        /// 委托函数
        /// </summary>
        Func<string, BazaarType> GetBazaarType = (str) =>
        {
            if (!string.IsNullOrEmpty(str) && str.Contains("_sh"))
            {
                return BazaarType.SH;
            }
            else if (!string.IsNullOrEmpty(str) && str.Contains("_sz"))
            {
                return BazaarType.SZ;
            }
            return BazaarType.WZ;
        };

        /// <summary>
        /// 输出微信小程序；UWP
        /// </summary>
        /// <param name="tag">是否使用缓存</param>
        /// <param name="t"></param>
        /// <returns></returns>
        public MarketBriefTencent GetQtMarketWeChat(out string tag, string t)
        {
            tag = "1.硬查询";
            try
            {
                //两秒以内直接返回
                if (stockData != null && stockData.StockList != null && stockData.StockList.Count > 0 && (DateTime.Now < Convert.ToDateTime(stockData.UpdateTime).AddMilliseconds(2000)))
                {
                    tag = "0.用缓存";
                    return stockData;
                }
                
                var ret = GetQtMarketWeichar();
                string[] zsArr = ret.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                if (zsArr.Length > 0)
                {
                    stockData.UpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
                }
                else
                {
                    return null;
                }

                //MarketBriefTencent data = new MarketBriefTencent();   //使用全局缓存起来
                stockData.StockList = new List<MarketBriefStock>();
                stockData.StockETFList = new List<MarketBriefStock>();
                stockData.StockWeightList = new List<MarketBriefStock>();
                stockData.StockGangMeiList = new List<MarketBriefStock>();
                stockData.MarketCountList = new List<MarketBriefCount>();
                stockData.zdt = new MarketModel();

                for (int i = 0; i < zsArr.Length; i++)
                {
                    try
                    {
                        //异常数据太短跳过
                        if (zsArr[i].Length < 20)
                        {
                            continue;
                        }

                        string[] arr = zsArr[i].Split(new char[] { '~' }, StringSplitOptions.RemoveEmptyEntries);

                        //委托函数，计算涨跌停家数
                        Func<string, string> GetSName = (str) =>
                        {
                            if (str == "Rank_A_sh")
                            {
                                return "上证";
                            }
                            else if (str == "Rank_A_sz")
                            {
                                return "深证";
                            }
                            return "";
                        };
                        if (arr != null && arr.Length >= 0)
                        {
                            //行情涨跌家数
                            if (t.Contains(((int)StockType.MarketCountList).ToString()) && (arr[1] == "Rank_A_sh" || arr[1] == "Rank_A_sz"))
                            {
                                stockData.MarketCountList.Add(new MarketBriefCount
                                {
                                    StockName = GetSName(arr[1]),
                                    ZhangCount = arr[2],
                                    DieCount = arr[4],
                                    PingCount = arr[3]
                                });
                            }
                            //指数行情
                            else if (t.Contains(((int)StockType.StockList).ToString()) && (arr[1] == "上证指数" || arr[1] == "创业板指" || arr[1] == "深证成指"))
                            {
                                //委托函数，计算成交量
                                Func<string, string> GetCjl = (str) =>
                                {
                                    var cjl = (Convert.ToDouble(arr[6]) / 100000000);
                                    if (cjl >= 1)
                                    {
                                        //保留两位小数
                                        return cjl.ToString("f2") + "亿手";
                                    }
                                    return (cjl * 10000).ToString("f0") + "万手";
                                };

                                var ms = new MarketBriefStock();
                                ms.StockName = arr[1];
                                ms.StockCode = arr[2];
                                ms.BazaarType = GetBazaarType(arr[0]);
                                ms.XianJia = arr[3];
                                ms.ZhangDieFu = arr[5];
                                ms.ZhangDieJia = arr[4];
                                ms.ChengJiaoLiang = GetCjl(arr[6]);
                                ms.ChengJiaoe = (Convert.ToDouble(arr[7]) / 10000).ToString("f2") + "亿";

                                stockData.StockList.Add(ms);
                            }
                            //ETF行情
                            else if (t.Contains(((int)StockType.StockETFList).ToString()) && (arr[1].Contains("ETF") || arr[1] == "创业板50" || arr[1] == "广发医药" || arr[1] == "MSCIA股" || arr[1] == "中 小 板" || arr[1] == "创业板" || arr[1] == "" || arr[1] == ""))
                            {
                                var ms = new MarketBriefStock();
                                ms.StockName = arr[1];
                                ms.StockCode = arr[2];
                                ms.BazaarType = GetBazaarType(arr[0]);
                                ms.XianJia = arr[3];
                                ms.ZhangDieFu = arr[5];
                                ms.ZhangDieJia = arr[4];
                                stockData.StockETFList.Add(ms);
                            }
                            //美股、港股
                            else if (t.Contains(((int)StockType.StockGangMeiList).ToString()) && (arr[0].Contains("s_hk") || arr[0].Contains("s_us") || arr[1].Contains("道琼斯") || arr[1] == "纳斯达克" || arr[1] == "恒生指数"))
                            {
                                stockData.StockGangMeiList.Add(new MarketBriefStock
                                {
                                    StockName = arr[1].Replace("-W", ""),
                                    StockCode = arr[2].Replace(".", "").Replace("OQ", "").Replace("oq", ""),
                                    BazaarType = GetBazaarType(arr[0]),
                                    //保留两位小数
                                    XianJia = Convert.ToDouble(arr[3]).ToString("0.00"),
                                    ZhangDieFu = arr[5],
                                    ZhangDieJia = arr[4]
                                });
                            }
                            //权重行情 IsStartWith
                            else if (t.Contains(((int)StockType.StockWeightList).ToString()) && (arr[0].Contains("v_s_sh60") || arr[0].Contains("v_s_sz00") || arr[0].Contains("v_s_sz30")))
                            {
                                stockData.StockWeightList.Add(new MarketBriefStock
                                {
                                    StockName = arr[1],
                                    StockCode = arr[2],
                                    BazaarType = GetBazaarType(arr[0]),
                                    XianJia = arr[3],
                                    ZhangDieFu = arr[5],
                                    ZhangDieJia = arr[4]
                                });
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        log.InfoFormat("StockBLL/GetQtMarketWeChat Fail-{0}", ex.ToString());
                    }
                }

                try
                {
                    if (t.Contains(((int)StockType.zdt).ToString()))
                    {
                        stockData.zdt = GetZdt();
                    }
                }
                catch (Exception ex)
                {
                    log.InfoFormat("StockBLL/GetQtMarketWeChat-GetZdt Fail-{0}", ex.ToString());
                }
                stockData.MksState = GetMksState();
            }
            catch (Exception ex)
            {
                log.InfoFormat("StockBLL/GetQtMarketWeChat Fail-{0}", ex.ToString());
            }
            return stockData;
        }

        /// <summary>
        /// 计算交易状态，集合竞价、交易中、已收盘、已休市
        /// 周末节假日显示已休市
        /// </summary>
        /// <returns></returns>
        public string GetMksState()
        {
            try
            {
                DateTime dtime = DateTime.Now;
                //dtime = Convert.ToDateTime("2019-04-17 14:46:00");

                var holi = GetHoliDay(dtime.ToString("yyyyMMdd"));
                if (holi != null && holi.data != "0")
                {
                    return MksState.已休市.ToString();
                }

                //获取当前日期是星期几
                string week = dtime.DayOfWeek.ToString();
                switch (week)
                {
                    case "Monday":
                        break;
                    case "Tuesday":
                        break;
                    case "Wednesday":
                        break;
                    case "Thursday":
                        break;
                    case "Friday":
                        break;
                    case "Saturday":
                        return MksState.已休市.ToString();
                    case "Sunday":
                        return MksState.已休市.ToString();
                }

                if (dtime > dtime.Date.AddHours(6).AddMinutes(0) && dtime < dtime.Date.AddHours(9).AddMinutes(15))
                {
                    return MksState.未开盘.ToString();
                }
                if (dtime > dtime.Date.AddHours(9).AddMinutes(15) && dtime < dtime.Date.AddHours(9).AddMinutes(25))
                {
                    return MksState.集合竞价.ToString();
                }
                if (dtime > dtime.Date.AddHours(9).AddMinutes(25) && dtime < dtime.Date.AddHours(9).AddMinutes(30))
                {
                    //return "开始成交";
                    return MksState.集合竞价.ToString();
                }
                //交易日 去除非交易时间
                if ((dtime > dtime.Date.AddHours(0).AddMinutes(0) && dtime < dtime.Date.AddHours(2).AddMinutes(0)) || (dtime > dtime.Date.AddHours(11).AddMinutes(30) && dtime < dtime.Date.AddHours(13).AddMinutes(0)) 
                    || dtime > dtime.Date.AddHours(15).AddMinutes(0))
                {
                    return MksState.已收盘.ToString();
                }
                return MksState.交易中.ToString();
            }
            catch (Exception ex)
            {
                var logInfo = string.Format("StockBLL/GetMksState Fail-{0}",ex.ToString());
            }
            return null;
        }


        /// <summary>
        /// 获取节假日api
        /// 工作日对应结果为 0, 休息日对应结果为 1, 节假日对应的结果为 2
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        private HoliDayModel GetHoliDay(string date)
        {
            try
            {
                var nTime = DateTime.Now;
                //今日已经访问过 则使用缓存
                if (holi != null && holi.data != null && holi.UpdateDateTime.Date == nTime.Date)
                {
                    return holi;
                }

                //当日5分钟以内也直接返回
                if (holi != null && holi.data != null && nTime < nTime.Date.AddHours(0).AddMinutes(5))
                {
                    log.InfoFormat("当日5分钟以内; 跳过节假日Api {0}", nTime.ToString("yyyy-MM-dd HH:mm:ss"));
                    return holi;
                }

                //节假日api：{"code":10001,"data":2} 工作日对应结果为 0, 休息日对应结果为 1, 节假日对应的结果为 2 
                JsonRequest request = new JsonRequest();
                var holiStr = request.Get(holidaysApi + date, null, Encoding.GetEncoding("gb2312"));

                log.InfoFormat("StockBLL/GetHoliDay 获取节假日Api-{0}", holiStr);

                //字典解析json
                //Dictionary<string, string> holi = JsonCommon.JsonDeserialize<Dictionary<string, string>>(holiStr);
                //var test = holi["data"];

                holi = JsonCommon.JsonToMode2<HoliDayModel>(holiStr);
                holi.UpdateDateTime = DateTime.Now;
                return holi;
            }
            catch (Exception ex)
            {
                log.InfoFormat("StockBLL/GetHoliDay 获取节假日Api Fail-{0}", ex.ToString());
                return null;
            }
        }


        /// <summary>
        /// 获取腾讯网 上证指数，创业板指，ETF基金、权重、沪A，深A 涨跌家数
        /// 输出小程序
        /// </summary>
        /// <returns></returns>
        public string GetQtMarketWeichar()
        {
            string url = null;
            string result = null;
            try
            {
                //大盘权重，ETF
                //http://qt.gtimg.cn/?q=s_sh000001,s_sz399001,s_sz399006,s_usDJI,s_usIXIC,s_hkHSI,s_sh510050,s_sz159949,s_sz159938,s_sh512070,s_sh510880,s_sh510180,s_sh512990,s_sh518880,s_sh512800,s_sh510300,s_sz159902,s_sz159915,s_sz159920,s_sh513100,s_sh512660,s_sh512980,s_sh510160,s_sz159928,s_sh510230,s_sh601398,s_sh600519,s_sh601628,s_sh600036,s_sh601088,s_sh600104,s_sh600900,s_sh601668,s_sh601766,s_sh600030,s_sh601390,s_sz000651,s_sh600050,s_sz002594,s_sz000002,s_sh600018,s_sh601111,s_sh600019,s_sh600276,s_sh601688,s_sh600887,s_sh601989,s_sz000538,s_sh600048,s_sz002027,s_sz300059,s_sh600011,s_sh600585,s_sh603288,s_sh600518,s_sz002415,s_sz000858,s_sz002352,s_sz300104,s_sh600028,s_sh601360,s_sz000725,s_sh603993,s_sz001979,s_sh601006,s_sz000063,s_sh600196,s_sh600340,s_sh603799,s_sh600547,s_sh600398,s_sz300070,s_sz002230,s_sz000977,s_sh600688,s_sh601857&r=7797

                StringBuilder sb = new StringBuilder();
                sb.Append(zhiShu);
                                
                //ETF
                sb.Append(etfCode);

                //权重
                sb.Append(weightCode);

                //恒生、道琼斯、纳斯达克指数；港股、美股
                sb.Append(gangMeiCode);

                JsonRequest request = new JsonRequest();
                url = qtMarketUrl + sb.ToString() + "&r=" + random.Next(10, 10000) + "";
                result = request.Get(url, null, Encoding.GetEncoding("gb2312"));
            }
            catch (Exception ex)
            {
                var logInfo = string.Format("StockBLL/GetQtMarket url-{0}，result-{1}，Fail-{2}", url, result, ex.ToString());
                log.Info(logInfo);
                //StockCommBLL.SendEmail("系统异常", "StockBLL/GetQtMarket", logInfo);
            }
            return result;
        }

        public MarketBriefTencent GetStockBlock()
        {
            //o=0涨,o=1跌

            //腾讯行业涨幅、跌幅          
            //varlist_data={t:'01/averatio',p:1,total:9,l:10,o:0,data:'bkqt012055,bkqt012004,bkqt012061,bkqt012078,bkqt012071,bkqt012097,bkqt012094,bkqt012029,bkqt012006,bkqt012079'};
            //string tmtUpUrl = "http://stock.gtimg.cn/data/view/bdrank.php?t=01/averatio&p=1&o=0&l=10&v=list_data";
            //string tmtDownUrl = "http://stock.gtimg.cn/data/view/bdrank.php?t=01/averatio&p=1&o=1&l=10&v=list_data";

            //概念涨幅、跌幅
            //var list_data={t:'02/averatio',p:1,total:28,l:10,o:0,data:'bkqt026297,bkqt021403,bkqt021315,bkqt026548,bkqt026102,bkqt026510,bkqt021209,bkqt026340,bkqt026517,bkqt026569'};
            //string conceptUpUrl = "http://stock.gtimg.cn/data/view/bdrank.php?t=02/averatio&p=1&o=0&l=10&v=list_data";
            //string conceptDownUrl = "http://stock.gtimg.cn/data/view/bdrank.php?t=02/averatio&p=1&o=1&l=10&v=list_data";

            //去掉后面两位就是沪深 rankash
            //沪深A涨幅
            //var IndUpUrl = "http://stock.gtimg.cn/data/view/rank.php?t=ranka/chr&p=1&o=0&l=10&v=list_data";
            //var list_data={t:'rankash/chr',p:1,total:145,l:10,o:0,data:'sh603332,sh600157,sh600331,sh600552,sh600614,sh600604,sh603739,sh600783,sh603121,sh603220'};
            //沪深A跌幅
            //var IndDownUrl = "http://stock.gtimg.cn/data/view/rank.php?t=ranka/chr&p=1&o=1&l=10&v=list_data";
            //var list_data={t:'rankash/chr',p:1,total:145,l:10,o:1,data:'sh603900,sh603326,sh603032,sh603300,sh600156,sh600410,sh600225,sh603321,sh600462,sh600193'};
            //详情："1~N龙杰~603332~27.99~19.44~27.99~537~0~537~27.99~76944~27.98~71~27.97~7~27.96~20~27.95~9~0.00~0~0.00~0~0.00~0~0.00~0~0.00~0~14:44:59/27.99/10/S/27990/28716|14:05:07/27.99/10/S/27990/23376|13:56:41/27.99/3/S/8397/22346|13:56:05/27.99/2/S/5598/22267|13:42:25/27.99/2/S/5598/20425|13:41:34/27.99/10/S/27990/20294~20190117151500~8.55~43.98~27.99~27.99~27.99/537/1503063~537~150~0.18~24.67~~27.99~27.99~0.00~8.32~33.29~2.63~27.99~12.44~0.00~77051~27.99~~24.67";


            //深A涨幅
            //http://stock.gtimg.cn/data/view/rank.php?t=rankasz/chr&p=1&o=0&l=10&v=list_data
            //var list_data={t:'rankasz/chr',p:1,total:213,l:10,o:0,data:'sz002945,sz300116,sz000780,sz002509,sz002565,sz002622,sz002143,sz002002,sz300019,sz002606'};
            //深A跌幅
            //http://stock.gtimg.cn/data/view/rank.php?t=rankasz/chr&p=1&o=1&l=10&v=list_data
            //var list_data={t:'rankasz/chr',p:1,total:213,l:10,o:1,data:'sz300210,sz300249,sz002692,sz300539,sz300319,sz000692,sz002708,sz300018,sz002270,sz000018'};

            try
            {
                //3秒以内直接返回
                if (stockBlockData != null && stockBlockData.TmtUpList != null && stockBlockData.TmtUpList.Count > 0 && (DateTime.Now < Convert.ToDateTime(stockBlockData.UpdateTime).AddMilliseconds(3000)))
                {
                    log.InfoFormat("GetStockBlock 0.用缓存");
                    return stockBlockData;
                }
                
                stockBlockData.UpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");

                log.InfoFormat("GetStockBlock 1.硬查询");
                //行业
                stockBlockData.TmtUpList = GetMkBlock(tmtUpUrl, 1);
                stockBlockData.TmtDownList = GetMkBlock(tmtDownUrl, 1);

                //概念
                stockBlockData.ConceptUpList = GetMkBlock(conceptUpUrl, 1);
                stockBlockData.ConceptDownList = GetMkBlock(conceptDownUrl, 1);
                
                //个股
                stockBlockData.IndUpList = GetMkBlock(IndUpUrl, 2);
                stockBlockData.IndDownList = GetMkBlock(IndDownUrl, 2);
            }
            catch (Exception ex)
            {
                log.InfoFormat("StockBLL/GetStockBlock Fail-{0}", ex.ToString());
            }
            return stockBlockData;
        }

        /// <summary>
        /// 获取个股排行model
        /// </summary>
        /// <param name="url"></param>
        /// <param name="t">1板块,2个股</param>
        /// <returns></returns>
        public List<MarketBriefStock> GetMkBlock(string url, int t)
        {
            List<MarketBriefStock> mkList = new List<MarketBriefStock>();
            string result = null;
            try
            {
                JsonRequest request = new JsonRequest();
                url += "&r=" + random.Next(10, 10000) + "";
                var str = request.Get(url, null, Encoding.GetEncoding("gb2312"));

                str = str.Substring((str.IndexOf("data:'") + 6));
                str = str.Remove(str.IndexOf("'};"));
                str = str.Replace("bkqt", "bkhz");

                request = new JsonRequest();
                url = qtMarketUrl + str + "&r=" + random.Next(10, 10000) + "";
                result = request.Get(url, null, Encoding.GetEncoding("gb2312"));

                string[] blArr = result.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                mkList = new List<MarketBriefStock>();

                if (blArr != null && blArr.Length > 0)
                {
                    for (int i = 0; i < blArr.Length; i++)
                    {
                        try
                        {
                            if (blArr[i].Length > 100)
                            {
                                mksModel = new MarketBriefStock();
                                if (t == 1)
                                {
                                    string[] mArr = blArr[i].Substring(result.IndexOf("=") + 2).Split(new char[] { '~' }, StringSplitOptions.RemoveEmptyEntries);
                                    mksModel.StockCode = mArr[0];
                                    mksModel.StockName = mArr[1];
                                    mksModel.CptionCount = mArr[5];
                                    mksModel.ZhangDieFu = mArr[8];
                                    mkList.Add(mksModel);
                                }
                                else if (t == 2)
                                {
                                    string[] mArr = blArr[i].Split(new char[] { '~' }, StringSplitOptions.RemoveEmptyEntries);
                                    mksModel.StockName = mArr[1];
                                    mksModel.StockCode = mArr[2];
                                    mksModel.BazaarType = GetBazaarType(mArr[0]);
                                    mksModel.XianJia = mArr[3];
                                    mksModel.ZhangDieFu = mArr[32];
                                    mkList.Add(mksModel);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            log.InfoFormat("StockBLL/GetMkBlock each url-{0}，result-{1}，Fail-{2}", url, result, ex.ToString());
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                log.InfoFormat("StockBLL/GetMkBlock url-{0}，result-{1}，Fail-{2}", url, result, ex.ToString());
            }
            return mkList;
        }


        #endregion



        /// <summary>
        /// 获取腾讯网 行情 上证指数，创业板指，沪A，深A 涨跌家数
        /// 接口查询单个股票代码，可拼接多个
        /// 用于API返回List对象，详细行情列表
        /// 接口有s_是简要行情，没有则是全部行情
        /// <param name="queryType">1详细行情，2简要行情</param>
        /// </summary>
        /// <returns></returns>
        public List<StockModel> GetQtMarketDetail(StockPoolReq param, int queryType = 0, string stockCode = null, BazaarType btype = 0)
        {
            //http://qt.gtimg.cn/q=sz000858
            //v_sz000858="51~五粮 液~000858~73.20~71.50~72.10~180664~98544~82088~73.20~133~73.18~30~73.17~1~73.16~26~73.15~5~73.31~35~73.33~2~73.37~47~73.38~211~73.39~1~10:09:09/73.20/677/S/4961662/1863|10:09:06/73.30/143/S/1046634/1861|10:09:04/73.32/41/S/298857/1860|10:09:00/73.35/129/S/946361/1857|10:08:57/73.37/275/S/2021485/1855|10:08:54/73.37/96/S/703698/1852~20190301100910~1.70~2.38~74.41~71.70~73.35/179803/1320285012~180664~132659~0.48~23.28~~74.41~71.70~3.79~2778.50~2841.34~4.77~78.65~64.35~2.50~-101~73.45~22.44~29.37"; 

            //http://qt.gtimg.cn/q=sh000001
            //v_sh000001="1~上证指数~000001~3027.58~2994.00~3015.94~525649436~262824019~262824019~0.00~0~0.00~0~0.00~0~0.00~0~0.00~0~0.00~0~0.00~0~0.00~0~0.00~0~0.00~0~15:00:13/3027.58/426906/M/318193850/71660|15:00:08/3027.46/2777443/M/2548451336/71656|15:00:03/3026.59/1097828/M/1099437664/71634|14:57:08/3026.22/3930/M/4423971/70769|14:57:03/3026.23/126266/M/120167568/70742|14:56:58/3026.17/209542/M/188514976/70720~20190304151557~33.57~1.12~3090.80~3006.94~3026.59/522445087/477737010276~525649436~48060366~~~~3090.80~3006.94~2.80~~~0.00~-1~-1~1.16~0~3039.28~~";

            //btype = BazaarType.SH;
            //stockCode = "000001";

            
            List<StockModel> list = new List<StockModel>();
            string url = null;
            string result = null;
            try
            {
                string pre = null;
                JsonRequest request = new JsonRequest();

                //自选股
                if (param != null && param.SelfStockList != null && param.SelfStockList.Count > 0)
                {
                    for (int i = 0; i < param.SelfStockList.Count; i++)
                    {
                        btype = param.SelfStockList[i].T;

                        if (btype == BazaarType.SH)
                        {
                            stockCode += "sh" + param.SelfStockList[i].C + ",";
                        }
                        else if (btype == BazaarType.SZ)
                        {
                            stockCode += "sz" + param.SelfStockList[i].C + ",";
                        }
                    }
                    stockCode = stockCode.Substring(0, stockCode.LastIndexOf(','));
                }
                //个股搜索
                else if (!string.IsNullOrEmpty(stockCode))
                {
                    if (queryType == 2)
                    {
                        pre = "s_";
                    }

                    if (btype == BazaarType.SH)
                    {
                        stockCode = pre + "sh" + stockCode;
                    }
                    else if (btype == BazaarType.SZ)
                    {
                        stockCode = pre + "sz" + stockCode;
                    }
                }
                else
                {
                    return null;
                }

                //http://qt.gtimg.cn/?q=sh600000,sz000001&r=9575
                url = qtMarketUrl + stockCode + "&r=" + random.Next(10, 10000) + "";
                result = request.Get(url, null, Encoding.GetEncoding("gb2312"));

                string[] stocksArr = result.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                StockModel model = null;
                for (int i = 0; i < stocksArr.Length; i++)
                {
                    try
                    {
                        if (stocksArr[i].Length < 50)
                        {
                            continue;
                        }

                        model = new StockModel();
                        string[] arr = stocksArr[i].Split('~');
                        string nameStr = "";

                        if (arr != null && arr.Length >= 0)
                        {
                            //委托函数，计算成交量
                            Func<string, string> GetCjl = (str) =>
                            {
                                if (!string.IsNullOrEmpty(str))
                                {
                                    var cjl = (Convert.ToDouble(arr[6]) / 100000000);
                                    if (cjl >= 1)
                                    {
                                        //保留两位小数
                                        return cjl.ToString("f2") + "亿手";
                                    }
                                    return (cjl * 10000).ToString("f2") + "万手";
                                }
                                return "";
                            };

                            nameStr = arr[0];
                            model.StockCode = nameStr.Substring((nameStr.IndexOf('=') - 8), 8);
                            if (model.StockCode.StartsWith("sh"))
                            {
                                model.StockCode = model.StockCode.Substring(2);
                                model.BazaarType = BazaarType.SH;
                            }
                            else if (model.StockCode.StartsWith("sz"))
                            {
                                model.StockCode = model.StockCode.Substring(2);
                                model.BazaarType = BazaarType.SZ;
                            }


                            //详细行情
                            if (queryType == 1)
                            {
                                model.StockName = arr[1];

                                model.xj = string.IsNullOrEmpty(arr[3]) ? 0 : Convert.ToDouble(arr[3]);
                                model.zsj = string.IsNullOrEmpty(arr[4]) ? 0 : Convert.ToDouble(arr[4]);
                                model.kpj = string.IsNullOrEmpty(arr[5]) ? 0 : Convert.ToDouble(arr[5]);
                                model.WaiPan = arr[7];
                                model.Neipan = arr[8];
                                model.m1 = string.IsNullOrEmpty(arr[9]) ? 0 : Convert.ToDouble(arr[9]);
                                //model.ma = arr[19];

                                model.zde = arr[31];
                                model.zdf = arr[32];
                                model.zgj = string.IsNullOrEmpty(arr[41]) ? 0 : Convert.ToDouble(arr[41]);
                                model.zdj = string.IsNullOrEmpty(arr[42]) ? 0 : Convert.ToDouble(arr[42]);
                                //var 最高 = arr[41];
                                //var 最低 = arr[42];

                                //价格/成交量（手）/成交额  
                                var t1 = arr[35];

                                //成交量手（换算，亿手/万手）  
                                model.Cjl = GetCjl(arr[36]);//成交手数，成交量
                                                            //成交额（换算亿，万）
                                model.Cje = string.IsNullOrEmpty(arr[37]) ? "" : (Convert.ToDouble(arr[37]) / 10000).ToString("f2") + "亿";  //成交额（亿）

                                model.Hsl = string.IsNullOrEmpty(arr[38]) ? "NaN" : arr[38] + "%";
                                model.Syl = string.IsNullOrEmpty(arr[39]) ? "NaN" : arr[39];
                                model.zhenFu = string.IsNullOrEmpty(arr[43]) ? "" : arr[43] + "%";
                                model.Ltsz = string.IsNullOrEmpty(arr[44]) ? "NaN" : Convert.ToDouble(arr[44]).ToString("f0") + "亿";
                                model.Zsz = string.IsNullOrEmpty(arr[45]) ? "NaN" : Convert.ToDouble(arr[45]).ToString("f0") + "亿";
                                model.Sjl = arr[46] == "0.00" ? "NaN" : arr[46];
                                model.Ztj = arr[47];
                                model.Dtj = arr[48];

                            }
                            //简要行情
                            else if (queryType == 2)
                            {
                                model.StockName = arr[1];
                                model.xj = string.IsNullOrEmpty(arr[3]) ? 0 : Convert.ToDouble(arr[3]);
                                model.cjgs = string.IsNullOrEmpty(arr[6]) ? 0 : Convert.ToDouble(arr[6]) / 100;//成交手数，成交量
                                model.cjje = string.IsNullOrEmpty(arr[7]) ? 0 : Convert.ToDouble(arr[7]) / 10000;  //成交额（亿）
                                model.zde = arr[4];
                                model.zdf = arr[5];
                            }
                        }
                        list.Add(model);
                    }
                    catch (Exception ex)
                    {
                        log.InfoFormat("StockBLL/GetQtMarketList url-{0}，result-{1}，Fail-{2}", url, result, ex.ToString());
                    }
                }
                
                //list.AddRange(top3);
            }
            catch (Exception ex)
            {
                log.InfoFormat("StockBLL/GetQtMarketList url-{0}，result-{1}，Fail-{2}", url, result, ex.ToString());
                //StockCommBLL.SendEmail("系统异常", "StockBLL/GetQtMarketList", logInfo);
            }
            return list;
        }



        /// <summary>
        /// 获取腾讯网2 行情 上证指数，创业板指，沪A，深A 涨跌家数
        /// 返回List对象，主要行情列表
        /// </summary>
        /// <param name="type">1自选股，2大盘，3查询单个个股（api）</param>
        /// <param name="sort">0正常排序，1按涨跌排序</param>
        /// <returns></returns>
        public List<StockModel> GetQtMarketList(int type, int sort = 0, string stockCode = null, BazaarType btype = 0)
        {
            List<StockModel> list = new List<StockModel>();
            string url = null;
            string result = null;
            try
            {
                JsonRequest request = new JsonRequest();
                DataTable dt = null;
                if (type == 1 || type == 2)
                {
                    //获取股票代码
                    StockDAL dal = new StockDAL();
                    dt = dal.GetTencentStockList(type);

                    //string stockCode = null;
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        if ((i + 1) == dt.Rows.Count)
                        {
                            stockCode += "s_" + dt.Rows[i]["代码"].ToString();
                        }
                        else
                        {
                            stockCode += "s_" + dt.Rows[i]["代码"].ToString() + ",";
                        }
                    }
                    url = qtMarketUrl + stockCode + "&r=" + random.Next(10, 10000) + "";
                }
                //接口查询单个股票代码
                else if (type == 3 && !string.IsNullOrEmpty(stockCode))
                {
                    if (btype == BazaarType.SH)
                    {
                        stockCode = "s_sh" + stockCode;
                    }
                    else if (btype == BazaarType.SZ)
                    {
                        stockCode = "s_sz" + stockCode;
                    }

                    url = qtMarketUrl + stockCode + "&r=" + random.Next(10, 10000) + "";
                }

                result = request.Get(url, null, Encoding.GetEncoding("gb2312"));

                //v_sz300059 = "51~东方财富~300059~19.50~18.55~20.00~8109633~3622099~4487366~19.49~235~19.48~1047~19.47~1052~19.46~509~19.45~2126~19.50~9724~19.51~4564~19.52~4645~19.53~2953~19.54~171~15:00:04/19.50/74748/S/145757235/10379|14:57:04/19.53/989/B/1932628/10278|14:57:00/19.52/1046/S/2040649/10276|14:56:58/19.52/1289/B/2514666/10274|14:56:55/19.50/12933/S/25226660/10272|14:56:52/19.52/1366/B/2666550/10270~20190226153004~0.95~5.12~20.41~19.41~19.50/8109633/16265390250~8109633~1626539~19.52~102.82~~20.41~19.41~5.39~809.94~1007.82~7.04~20.41~16.70~2.61~-17088~20.05~94.38~158.24";


                string[] stocksArr = result.Split(';');
                StockModel model = null;
                for (int i = 0; i < stocksArr.Length; i++)
                {
                    if (stocksArr[i].Length < 50)
                    {
                        continue;
                    }

                    model = new StockModel();
                    string[] arr = stocksArr[i].Split('~');
                    string nameStr = "";
                    if (arr != null && arr.Length >= 0)
                    {
                        nameStr = arr[0];
                        model.StockCode = nameStr.Substring((nameStr.IndexOf('=') - 8), 8);
                        if (model.StockCode.Contains("sh") || model.StockCode.Contains("sz"))
                        {
                            model.StockCode = model.StockCode.Substring(2);
                        }


                        model.StockName = arr[1];
                        model.xj = Convert.ToDouble(arr[3]);
                        model.cjgs = Convert.ToDouble(arr[6]) / 100;//成交手数，成交量
                        model.cjje = Convert.ToDouble(arr[7]) / 10000;  //成交额（亿）
                        model.zde = arr[4];
                        model.zdf = arr[5];

                        if (type == 1 || type == 2)
                        {
                            model.ID = dt.Rows[i]["ID"] == DBNull.Value ? 0 : Convert.ToInt32(dt.Rows[i]["ID"]);
                            model.Type = dt.Rows[i]["Type"].ToString();
                            model.StockLevel = dt.Rows[i]["StockLevel"] == DBNull.Value ? 0 : Convert.ToInt32(dt.Rows[i]["StockLevel"]);
                            model.Sort = dt.Rows[i]["Sort"] == DBNull.Value ? 0 : Convert.ToInt32(dt.Rows[i]["Sort"]);
                        }
                    }
                    list.Add(model);
                }

                //排序规则：持仓置顶 -> 靠前 -> 普通排序
                List<StockModel> top1 = list.Where(s => s.StockLevel == 1).OrderBy(s => s.Sort).ToList();
                List<StockModel> top2 = list.Where(s => s.StockLevel == 2).OrderBy(s => s.Sort).ToList();
                List<StockModel> top3 = list.Where(s => s.StockLevel == 0).OrderBy(s => s.Sort).ToList();

                list = top1;
                list.AddRange(top2);
                list.AddRange(top3);
            }
            catch (Exception ex)
            {
                log.InfoFormat("StockBLL/GetQtMarketList url-{0}，result-{1}，Fail-{2}", url, result, ex.ToString());
                //StockCommBLL.SendEmail("系统异常", "StockBLL/GetQtMarketList", logInfo);
            }
            return list;
        }
        

        
        /// <summary>
        /// 获取新浪行情，个股，指数
        /// 提醒、监控
        /// PC调用
        /// </summary>
        /// <returns></returns>
        public List<string> GetSinaMarket()
        {
            JsonRequest request = new JsonRequest();
            string url = null;
            string result = null;
            List<StockModel> stockList = null;
            List<string> tips = null;
            try
            {
                //获取股票代码
                StockDAL dal = new StockDAL();
                DataTable dt = dal.GetSinaStockList();

                string stockCode = null;
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    if ((i + 1) == dt.Rows.Count)
                    {
                        stockCode += dt.Rows[i]["代码"].ToString();
                    }
                    else
                    {
                        stockCode += dt.Rows[i]["代码"].ToString() + ",";
                    }
                }

                url = sinaStockPortUrl + stockCode;
                result = request.Get(url,null, Encoding.GetEncoding("gb2312"));

                //var pageList = JsonCommon.JsonToMode<StockModel>(result);
                stockList = GetStockInfo(result);

                //计算符合条件的涨跌，并入库
                tips = GetTips(stockList, dt);
                                
                //提醒操作，邮件发送   --字符串改为列表
                //if (tips != null && tips.Count > 0)
                //{
                //    if (StockCommBLL.GetConfig("IsSendEmail") == "1")
                //    {
                //        string title = tips.Trim().Replace("\r\n", "；");
                //        if (title.Length >= 65)
                //        {
                //            title = title.Substring(0, 65 - 1);
                //        }
                //        else
                //        {
                //            title = title.Substring(0, title.Length - 1);
                //        }

                //        StockCommBLL.SendEmail("股票异动提醒", title, tips);
                //    }
                //    //MessTip(tips);
                //}
            }
            catch (Exception ex)
            {
                var logInfo = string.Format("StockBLL/GetSinaMarket url-{0}，result-{1}，Fail-{2}", url, result, ex.ToString());
                log.Info(logInfo);
                //StockCommBLL.SendEmail("系统异常", "StockBLL/GetSinaMarket", logInfo);
            }
            return tips;
        }


        /// <summary>
        /// 计算符合条件的提醒消息
        /// 计算符合数据库配置时间，间隔等
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private List<string> GetTips(List<StockModel> list, DataTable dt)
        {
            //提醒tips
            List<string> tipList = new List<string>();
            string sql = "";
            //log4 输出日志
            string tipLog = "           \r\n";
            string levTag = ""; //获取标记
            string levTagID = "";
            try
            {
                StockModel model = null;
                //double shangzj = 0;
                //double xiadj = 0;
                double txf = 0; //梯形幅

                DataTable dtt = null;
                for (int i = 0; i < list.Count; i++)
                {
                    try
                    {
                        model = list[i];
                        model.StockLevel = dt.Rows[i]["StockLevel"] == DBNull.Value ? 0 : Convert.ToInt32(dt.Rows[i]["StockLevel"]);
                        //停牌
                        if (model.kpj.ToString("0.0") == "0.0")
                        {
                            continue;
                        }

                        levTag = GetLevelTag(model.StockLevel);
                        levTagID = model.StockCode + "@" + levTag;

                        #region 时间间隔控制 未启用
                        /*
                        //首先检查当前代码提醒间隔
                        if (!string.IsNullOrEmpty(dt.Rows[i]["提醒间隔"].ToString()))
                        {
                            tiXing = Convert.ToDouble(dt.Rows[i]["提醒间隔"]);
                        }
                        else
                        {
                            tiXing = tiXingDefault;
                        }

                        if (dt.Rows[i]["提醒时间"] == DBNull.Value && DateTime.Now < Convert.ToDateTime(dt.Rows[i]["提醒时间"]).AddMinutes(tiXing))
                        {
                            continue;
                        } */

                        #endregion


                        #region 涨跌价格提醒


                        if (!string.IsNullOrEmpty(dt.Rows[i]["涨跌到价"].ToString()))
                        {
                            string[] zddjArr = dt.Rows[i]["涨跌到价"].ToString().Split(',');
                            //到价直接写入无需做上涨/下跌判断（2.3/5.5/10.2）
                            string zdjLog = dt.Rows[i]["涨跌到价Log"].ToString();

                            foreach (var item in zddjArr)
                            {
                                //log.Info("item-"+ item);
                                //上涨
                                if (!string.IsNullOrEmpty(item) && Convert.ToDouble(item) > 0)
                                {
                                    if (model.xj > Convert.ToDouble(item))
                                    {
                                        //检查日志
                                        string[] zdjArr = dt.Rows[i]["涨跌到价Log"].ToString().Split(',');
                                        if (!zdjArr.Contains(item))
                                        {
                                            //tip += "" + model.StockName + " 现价" + model.xj.ToString("0.00") + "，上涨达到" + item + "" + (model.xj > 1000 ? "点" : "元") + "\r\n\r\n";
                                            tipList.Add(levTagID + "" + model.StockName + " 现价" + model.xj.ToString("0.00") + "，上涨达到" + item + "" + (model.xj > 1000 ? "点" : "元") + "");
                                            tipLog += "           " + levTag + model.StockName + " 现价" + model.xj.ToString("0.00") + "，上涨达到" + item + "" + (model.xj > 1000 ? "点" : "元") + "；\r\n\r\n";
                                            zdjLog += item + ",";
                                        }
                                    }
                                }
                                //下跌
                                else if (!string.IsNullOrEmpty(item) && Convert.ToDouble(item) < 0)
                                {
                                    if (model.xj < Math.Abs(Convert.ToDouble(item)))
                                    {
                                        //检查日志
                                        string[] zdjArr = dt.Rows[i]["涨跌到价Log"].ToString().Split(',');
                                        if (!zdjArr.Contains(item))
                                        {
                                            tipList.Add(levTagID + "" + model.StockName + " 现价" + model.xj.ToString("0.00") + "，下跌达到" + item + "" + (model.xj > 1000 ? "点" : "元") + "");
                                            tipLog += "           " + levTag + model.StockName + " 现价" + model.xj.ToString("0.00") + "，下跌达到" + item + "" + (model.xj > 1000 ? "点" : "元") + "；\r\n\r\n";
                                            zdjLog += item + ",";
                                        }
                                    }
                                }
                            }
                            //循环完毕插入日志
                            if (!string.IsNullOrEmpty(zdjLog) && zdjLog != dt.Rows[i]["涨跌到价Log"].ToString())
                            {
                                sql += "update 实时监控 set 涨跌到价Log='" + zdjLog + "' where ID=" + Convert.ToInt32(dt.Rows[i]["ID"]) + ";";
                            }
                        }


                        #endregion


                        #region 涨跌幅提醒

                        //重置涨跌幅
                        zhangFu = 0;
                        dieFu = 0;

                        //涨跌幅 = 涨跌值/昨收盘*100%
                        double zdf = GetZhangDieFu(model.xj, model.zsj);
                        string TypeStr = "";
                        if (zdf > 0)
                            TypeStr = "涨幅";
                        else if (zdf < 0)
                            TypeStr = "跌幅";
                        else
                            TypeStr = "持平";

                        //if (model.StockName == "贵阳银行")
                        //{

                        //}
                        //if (model.StockName == "长白山")
                        //{

                        //}
                        
                        //每一条数据使用自己的配置，如没有配置则使用默认配置
                        if (!string.IsNullOrEmpty(dt.Rows[i]["涨跌幅"].ToString()))
                        {
                            string[] zdfArr = dt.Rows[i]["涨跌幅"].ToString().Split(',');
                            if (zdfArr.Length == 1)
                            {
                                zhangFu = Convert.ToDouble(zdfArr[0]);
                                dieFu = Convert.ToDouble(zdfArr[0]);                                
                            }
                            else if (zdfArr.Length == 2)
                            {
                                zhangFu = Convert.ToDouble(zdfArr[0]);
                                dieFu = Convert.ToDouble(zdfArr[1]);  
                            }
                        }
                        //else
                        //{
                        //    zhangFu = zhangFuDefault;
                        //    dieFu = dieFuDefault;
                        //}
                        
                        //命中涨跌幅
                        if ((int)zhangFu != 0 && (int)dieFu != 0 && (zdf > zhangFu || zdf < -dieFu))
                        {
                            //今日已经提醒过，则不再提醒
                            string[] zdfLogArr = null;
                            if (!string.IsNullOrEmpty(dt.Rows[i]["涨跌幅Log"].ToString()))
                            {
                                zdfLogArr = dt.Rows[i]["涨跌幅Log"].ToString().Split(',');
                                if (zdfLogArr.Length > 1)
                                {
                                    if (zdf > 0 && string.IsNullOrEmpty(zdfLogArr[0].ToString()))
                                    {
                                        zdfLogArr[0] = "+1";
                                        sql += "update 实时监控 set 涨跌幅Log='" + string.Join(",", zdfLogArr) + "' where ID=" + Convert.ToInt32(dt.Rows[i]["ID"]) + ";";
                                    }
                                    else if (zdf < 0 && string.IsNullOrEmpty(zdfLogArr[1].ToString()))
                                    {
                                        zdfLogArr[1] = "-1";
                                        sql += "update 实时监控 set 涨跌幅Log='" + string.Join(",", zdfLogArr) + "' where ID=" + Convert.ToInt32(dt.Rows[i]["ID"]) + ";";
                                    }
                                }
                            }
                            else
                            {
                                tipList.Add(string.Format(levTagID + "" + model.StockName + " 现价" + model.xj.ToString("0.00") + "，" + TypeStr + "达到" + (TypeStr == "涨幅" ? "+" + zhangFu.ToString() : "-" + dieFu.ToString("0.00")) + "%"));
                                tipLog += "           " + levTag + model.StockName + " 现价" + model.xj.ToString("0.00") + "，" + TypeStr + "达到" + (TypeStr == "涨幅" ? "+" + zhangFu.ToString() : "-" + dieFu.ToString("0.00")) + "%；\r\n\r\n";

                                if (zdf > 0)
                                    sql += "update 实时监控 set 涨跌幅Log='+1,' where ID=" + Convert.ToInt32(dt.Rows[i]["ID"]) + ";";
                                else
                                    sql += "update 实时监控 set 涨跌幅Log=',-1' where ID=" + Convert.ToInt32(dt.Rows[i]["ID"]) + ";";
                            }
                        }

                        #endregion


                        #region 梯形提醒，根据昨收假

                        GetTiXinFu(dt, ref tipList, ref sql, ref tipLog, model, ref txf, dtt, i, 1);

                        #endregion   

                        #region 梯形提醒，计算当日从最高点跌到位提醒，当日最低点上涨到位提醒

                        //GetTiXinFu(dt, ref tipList, ref sql, ref tipLog, model, ref txf, dtt, i, 2);

                        #endregion                        
                        
                     
                    }
                    catch (Exception ex)
                    {
                        log.ErrorFormat("StockBLL/GetTips StockName{0}，tip-{1}，Fail-{2}",model.StockName, JsonCommon.ToJson<List<string>>(tipList), ex);
                    }
                }

                #region 有命中  統一更新日志
                if (tipList != null && tipList.Count > 0 && !string.IsNullOrEmpty(sql))
                {
                    log.InfoFormat("StockBLL/GetTips sql-{0}", sql);
                    string[] sqlArr = sql.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (var sqlStr in sqlArr)
                    {
                        SetDBBySql(sqlStr);
                    }
                }
                #endregion

                if (tipLog.Length > 20)
                {
                    log.Info(tipLog);
                }
            }
            catch (Exception ex)
            {
                log.ErrorFormat("StockBLL/GetTips tip-{0}，Fail-{1}", JsonCommon.ToJson<List<string>>(tipList), ex);
            }
            return tipList;
        }

    
        /// <summary>
        /// 计算梯形梯形，涨跌幅/最高最低价涨跌幅
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="tipList"></param>
        /// <param name="sql"></param>
        /// <param name="tipLog"></param>
        /// <param name="model"></param>
        /// <param name="txf"></param>
        /// <param name="dtt"></param>
        /// <param name="i"></param>
        /// <param name="type">1涨跌幅，2最高最低涨跌幅</param>
        private void GetTiXinFu(DataTable dt, ref List<string> tipList, ref string sql, ref string tipLog, StockModel model, ref double txf, DataTable dtt, int i, int type)
        {
            //这里不做时间控制，实时计算，到位立即提醒
            //计算当日从最高最低波段提醒，没上涨/下跌到位提醒

            //从最高价下跌幅
            double zgxdf = GetZhangDieFu(model.xj, type == 1 ? model.zsj : model.zgj);
            //从最低价上涨幅
            double zdszf = GetZhangDieFu(model.xj, type == 1 ? model.zsj : model.zdj);

            if (dt.Rows[i]["梯形幅"] != DBNull.Value)
            {
                //上涨幅度
                string[] txfArr = dt.Rows[i]["梯形幅"].ToString().Split(new char[] { ',' });
                //只有一个值，上涨/下跌通用
                if (txfArr != null && txfArr.Length == 1)
                {
                    //下跌
                    txf = -Convert.ToDouble(txfArr[0]);
                    if (zgxdf < txf)
                    {
                        if (Math.Abs(txf) != Math.Abs(Convert.ToInt32(dt.Rows[i]["涨跌幅"])))
                        {
                            GetTiXingFu(dt, ref tipList, ref tipLog, model, txf, dtt, i, ref zgxdf, ref sql, type);
                        }
                    }

                    //上涨
                    txf = Math.Abs(txf);
                    if (zdszf > txf)
                    {
                        if (Math.Abs(txf) != Math.Abs(Convert.ToInt32(dt.Rows[i]["涨跌幅"])))
                        {                            
                            GetTiXingFu(dt, ref tipList, ref tipLog, model, txf, dtt, i, ref zdszf, ref sql, type);
                        }
                    }
                }
                //两个值，左边上涨右边下跌
                else if (txfArr != null && txfArr.Length == 2)
                {
                    txf = -Convert.ToDouble(txfArr[1]);
                    if (zgxdf < txf)
                    {
                        if (Math.Abs(txf) != Math.Abs(Convert.ToInt32(dt.Rows[i]["涨跌幅"])))
                        {
                            GetTiXingFu(dt, ref tipList, ref tipLog, model, txf, dtt, i, ref zgxdf, ref sql, type);                            
                        }
                    }

                    //上涨
                    txf = Convert.ToDouble(txfArr[0]);
                    if (zdszf > txf)
                    {
                        if (Math.Abs(txf) != Math.Abs(Convert.ToInt32(dt.Rows[i]["涨跌幅"])))
                        {
                            GetTiXingFu(dt, ref tipList, ref tipLog, model, txf, dtt, i, ref zdszf, ref sql, type);                            
                        }
                    }
                }
            }

        }

        /// <summary>
        /// 根据权重获取标记
        /// </summary>
        /// <param name="lev"></param>
        /// <returns></returns>
        private string GetLevelTag(int lev)
        {
            if (lev == 1)
            {
                return "**";
            }
            else if (lev == 2)
            {
                return "*";
            }
            return "";
        }

        private void GetTiXingFu(DataTable dt, ref List<string> tips, ref string tipLog, StockModel model, double txf, DataTable dtt, int i, ref double zdf, ref string sql, int type)
        {
            try
            {
                string levTag = GetLevelTag(model.StockLevel);
                string levTagID = model.StockCode + "@" + levTag;

                //查询梯形Log计算
                dtt = new StockDAL().GetColumnByID("梯形数Log", Convert.ToInt32(dt.Rows[i]["ID"]));
                if (dtt != null && dtt.Rows.Count > 0)
                {
                    string[] logArr = dtt.Rows[0]["梯形数Log"].ToString().Split(new char[] { ',' });
                    if (logArr != null && logArr.Length > 1)
                    {
                        //如果已经有记录，需要判断涨跌幅的倍数，实现梯形提醒
                        //zgxdf = GetZhangDieFu(model.xj, model.zgj);
                        int c = Math.Abs(Convert.ToInt32(txf > 0 ? (string.IsNullOrEmpty(logArr[0].ToString()) ? "0" : logArr[0].ToString()) : (string.IsNullOrEmpty(logArr[1].ToString()) ? "0" : logArr[1].ToString()))) + 1;
                        //txf = (-Convert.ToDouble(dt.Rows[i]["梯形幅"])) * c;
                        txf = txf * c;

                        if (txf > 0)
                        {
                            if (zdf > txf)
                            {
                                tips.Add(string.Format(levTagID + "" + model.StockName + " 现价" + model.xj.ToString("0.00") + "，" + (type == 1 ? "涨幅达到" : "已从最低价上涨") + txf + "" + "%"));
                                tipLog += "           " + levTag + model.StockName + " 现价" + model.xj.ToString("0.00") + "，" + (type == 1 ? "涨幅达到" : "已从最低价上涨") + txf + "" + "%；\r\n\r\n";
                                //记录梯形Log
                                logArr[0] = "+" + c;
                                //sql += "update 实时监控 set 梯形数Log='" + string.Join(",", logArr) + "' where ID=" + Convert.ToInt32(dt.Rows[i]["ID"]) + ";";
                                SetDBBySql("update 实时监控 set 梯形数Log='" + string.Join(",", logArr) + "' where ID=" + Convert.ToInt32(dt.Rows[i]["ID"]) + ";");
                            }
                        }
                        else
                        {
                            if (zdf < txf)
                            {
                                tips.Add(string.Format(levTagID + "" + model.StockName + " 现价" + model.xj.ToString("0.00") + "，" + (type == 1 ? "跌幅达到" : "已从最高价下跌") + txf + "" + "%"));
                                tipLog += "           " + levTag + model.StockName + " 现价" + model.xj.ToString("0.00") + "，" + (type == 1 ? "跌幅达到" : "已从最高价下跌") + txf + "" + "%；\r\n\r\n";
                                //记录梯形Log
                                logArr[1] = "-" + c;
                                //sql += "update 实时监控 set 梯形数Log='" + string.Join(",", logArr) + "' where ID=" + Convert.ToInt32(dt.Rows[i]["ID"]) + ";";
                                SetDBBySql("update 实时监控 set 梯形数Log='" + string.Join(",", logArr) + "' where ID=" + Convert.ToInt32(dt.Rows[i]["ID"]) + ";");
                            }
                        }
                    }
                    else
                    {
                        //如果没有记录直接提醒、写入
                        if (txf > 0)
                        {
                            tips.Add(string.Format(levTagID + "" + model.StockName + " 现价" + model.xj.ToString("0.00") + "，" + (type == 1 ? "涨幅达到" : "已从最低价上涨") + txf + "" + "%"));
                            tipLog += "           " + levTag + model.StockName + " 现价" + model.xj.ToString("0.00") + "，" + (type == 1 ? "涨幅达到" : "已从最低价上涨") + txf + "" + "%；\r\n\r\n";
                            //sql += "update 实时监控 set 梯形数Log='+1,' where ID=" + Convert.ToInt32(dt.Rows[i]["ID"]) + ";";
                            SetDBBySql("update 实时监控 set 梯形数Log='+1,' where ID=" + Convert.ToInt32(dt.Rows[i]["ID"]) + ";");
                        }
                        else
                        {
                            tips.Add(string.Format(levTagID + "" + model.StockName + " 现价" + model.xj.ToString("0.00") + "，" + (type == 1 ? "跌幅达到" : "已从最高价下跌") + txf + "" + "%"));
                            tipLog += "           " + levTag + model.StockName + " 现价" + model.xj.ToString("0.00") + "，" + (type == 1 ? "跌幅达到" : "已从最高价下跌") + txf + "" + "%；\r\n\r\n";
                            //sql += "update 实时监控 set 梯形数Log=',-1' where ID=" + Convert.ToInt32(dt.Rows[i]["ID"]) + ";";
                            SetDBBySql("update 实时监控 set 梯形数Log=',-1' where ID=" + Convert.ToInt32(dt.Rows[i]["ID"]) + ";");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                log.ErrorFormat("StockBLL/GetTiXingFu Fail-{0}", ex);
            }
        }

        /// <summary>
        /// 操作数据库
        /// </summary>
        /// <param name="sql">操作sql</param>
        public void SetDBBySql(string sql, int milliscond = 0)
        {
            try
            {
                log.InfoFormat("当前线程：{0}", Thread.CurrentThread.ManagedThreadId);
                StockDAL dal = new StockDAL();
                int num = dal.ExecuteCommand(sql);
                if (milliscond > 0)
                    Thread.Sleep(milliscond);
            }
            catch (Exception ex)
            {
                log.ErrorFormat("StockBLL/SetDBBySql sql-{0}，Fail-{1}", sql, ex);
            }
        }

        /// <summary>
        /// 清理数据库提醒Log
        /// </summary>
        public void ClearLog()
        {
            string sql = null;
            try
            {
                log.InfoFormat("当前线程-清理：{0}", Thread.CurrentThread.ManagedThreadId);
                StockDAL dal = new StockDAL();
                int num = dal.ClearLog();
                log.InfoFormat("清空{0}条日志数据", num);
            }
            catch (Exception ex)
            {
                log.ErrorFormat("StockBLL/ClearLog sql-{0}，Fail-{1}", sql, ex);
            }
        }

        /// <summary>
        /// 读数实时监控表的所有股票代码
        /// </summary>
        /// <returns></returns>
        public DataTable GetRealTimeMonitoringList()
        {
            DataTable dt = null;
            try
            {
                StockDAL dal = new StockDAL();
                dt = dal.GetRealTimeMonitoringList();
            }
            catch (Exception ex)
            {
                log.ErrorFormat("StockBLL/GetRealTimeMonitoringList，Fail-{0}", ex);
            }
            return dt;
        }

        /// <summary>
        /// 测试写入
        /// </summary>
        public void InsertDBTest()
        {
            StockDAL dal = new StockDAL();

            for (int i = 0; i < 10; i++)
            {
                try
                {
                    dal.InsertDBTest(i);
                }
                catch (Exception ex)
                {
                    log.InfoFormat("InsertDBTest fail-{0}", ex);
                }
                log.InfoFormat("第{0}次写入数据", i);
            }
            

        }


        /// <summary>
        /// Api调用，获取股票对象列表
        /// 细微处理
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private static List<StockModel> GetStockInfo2(string str)
        {
            List<StockModel> stockList = new List<StockModel>();
            try
            {
                string[] stocksArr = str.Split(';');
                StockModel model = null;
                for (int i = 0; i < stocksArr.Length; i++)
                {
                    try
                    {
                        if (stocksArr[i].Length < 100)
                        {
                            continue;
                        }

                        model = new StockModel();
                        string[] arr = stocksArr[i].Split(',');
                        string nameStr = "";
                        if (arr != null && arr.Length >= 0)
                        {
                            nameStr = arr[0];
                            model.StockCode = nameStr.Substring((nameStr.IndexOf('=') - 8), 8);
                            if (model.StockCode.Contains("sh") || model.StockCode.Contains("sz"))
                            {
                                model.StockCode = model.StockCode.Substring(2);
                            }

                            model.StockName = nameStr.Substring((nameStr.IndexOf('=') + 2), ((nameStr.Length - nameStr.IndexOf('=')) - 2));
                            model.kpj = Convert.ToDouble(arr[1]);
                            model.zsj = Convert.ToDouble(arr[2]);
                            model.xj = Convert.ToDouble(arr[3]);
                            model.zgj = Convert.ToDouble(arr[4]);
                            model.zdj = Convert.ToDouble(arr[5]);
                            model.jm1 = Convert.ToDouble(arr[6]);
                            model.jmai1 = Convert.ToDouble(arr[7]);
                            model.cjgs = Convert.ToDouble(arr[8]);
                            model.cjje = Convert.ToDouble(arr[9]);
                            model.msqg = Convert.ToDouble(arr[10]);
                            model.m1 = Convert.ToDouble(arr[11]);

                            model.date = arr[30];
                            model.time = arr[31];
                        }
                        stockList.Add(model);
                    }
                    catch (Exception ex)
                    {
                        log.ErrorFormat("StockBLL/GetStockInfo stocksArr[{0}]:{1} Fail-{2}", stocksArr[i], stocksArr[i], ex);
                    }
                }
            }
            catch (Exception ex)
            {
                log.ErrorFormat("StockBLL/GetStockInfo Fail-{0}", ex);
            }
            return stockList;
        }

        /// <summary>
        /// 获取股票对象列表
        /// pc调用
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private static List<StockModel> GetStockInfo(string str)
        {
            List<StockModel> stockList = new List<StockModel>();
            try
            {
                string[] stocksArr = str.Split(';');
                StockModel model = null;
                for (int i = 0; i < stocksArr.Length; i++)
                {
                    try
                    {
                        if (stocksArr[i].Length < 100)
                        {
                            continue;
                        }

                        model = new StockModel();
                        string[] arr = stocksArr[i].Split(',');
                        string nameStr = "";
                        if (arr != null && arr.Length >= 0)
                        {
                            nameStr = arr[0];
                            model.StockCode = nameStr.Substring((nameStr.IndexOf('=') - 8), 8);
                            model.StockName = nameStr.Substring((nameStr.IndexOf('=') + 2), ((nameStr.Length - nameStr.IndexOf('=')) - 2));
                            model.kpj = Convert.ToDouble(arr[1]);
                            model.zsj = Convert.ToDouble(arr[2]);
                            model.xj = Convert.ToDouble(arr[3]);
                            model.zgj = Convert.ToDouble(arr[4]);
                            model.zdj = Convert.ToDouble(arr[5]);
                            model.jm1 = Convert.ToDouble(arr[6]);
                            model.jmai1 = Convert.ToDouble(arr[7]);
                            model.cjgs = Convert.ToDouble(arr[8]);
                            model.cjje = Convert.ToDouble(arr[9]);
                            model.msqg = Convert.ToDouble(arr[10]);
                            model.m1 = Convert.ToDouble(arr[11]);

                            model.date = arr[30];
                            model.time = arr[31];
                        }
                        stockList.Add(model);
                    }
                    catch (Exception ex)
                    {
                        log.ErrorFormat("StockBLL/GetStockInfo stocksArr[{0}]:{1} Fail-{2}", stocksArr[i], stocksArr[i], ex);
                    }
                }
            }
            catch (Exception ex)
            {
                log.ErrorFormat("StockBLL/GetStockInfo Fail-{0}", ex);
            }
            return stockList;
        }

        /// <summary>
        /// 计算涨跌幅涨跌幅
        /// 公式：一件物品原价25,现价75,计算涨幅比率
        /// =(75-25)/25*100
        /// =200%
        /// <param name="xj">现价</param>
        /// <param name="zsj">昨收价</param>
        /// <returns></returns>
        private double GetZhangDieFu(double xj, double zsj)
        {
            double zdf = (xj - zsj) / zsj * 100;
            return Math.Round(zdf, 2);
        }

        /// <summary>
        /// 判断字符是否以某字符串开头
        /// </summary>
        /// <param name="source"></param>
        /// <param name="str"></param>
        /// <returns></returns>
        private bool IsStartWith(string text, string str)
        {
            if (text.StartsWith(str.Trim()))
            {
                return true;
            }
            return false;
        }


    }
}
